﻿/*======================================================================
== Copyright : BlueCurve (c)
== Licence   : Gnu/GPL v2.x
== Author    : Teddy Albina
== Email     : bluecurveteam@gmail.com
== Web site  : http://www.codeplex.com/BlueCurve
========================================================================*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QueryServer
{
    /// <summary>
    /// Class de gestion du cache mémoire
    /// </summary>
    /// <typeparam name="Tvalue">Type de clef</typeparam>
    /// <typeparam name="Tid">Type d'identifiant</typeparam>
    /// <typeparam name="Tdata">Type de données</typeparam>
    public class Cache<Tvalue, Tid, Tdata> : BlueCurve.MemoryCache.IKeysCache<Tvalue, Tid, Tdata>
    {
        #region 'Configuration'

        /// <summary>
        /// Instance local de la class
        /// http://msdn.microsoft.com/en-us/library/ms998558.aspx
        /// </summary>
        private static volatile Cache<Tvalue, Tid, Tdata> Instance;
        /// <summary>
        /// Objet pour la synchronisation
        /// </summary>
        private static readonly object myLock = new object();
        /// <summary>
        /// Instance du cache mémoire
        /// </summary>
        private static BlueCurve.MemoryCache.KeysCache<Tvalue, Tid, Tdata> QueryCache = new BlueCurve.MemoryCache.KeysCache<Tvalue, Tid, Tdata>()
        {
             LifeTime = 1200 * 1000 // 20 minutes
        };
        


        /// <summary>
        /// Obtient une instance de la classe
        /// </summary>
        public static Cache<Tvalue, Tid, Tdata> GetInstance
        {
            get
            {
                if (Instance == null)
                {
                    lock (myLock)
                    {
                        if (Instance == null)
                        {
                            Instance = new Cache<Tvalue, Tid, Tdata>();
                            BlueCurve.MemoryCache.StopCache.StopTheCache += new EventHandler(StopCache_StopTheCache);
                        }
                    }
                }
                return Instance;
            }
        }

        #endregion

        

        #region IKeysCache<Tvalue,Tid,Tdata> Membres

        /// <summary>
        /// Ajout de données dans le cache
        /// </summary>
        /// <param name="value">Valeur à ajouter dans le cache</param>
        /// <param name="id">Identifiant</param>
        /// <param name="data"></param>
        public void Add(Tvalue value, Tid id, Tdata data)
        {
            QueryCache.Add(value, id, data);
        }

        /// <summary>
        /// Vide le cache
        /// </summary>
        public void Clear()
        {
            QueryCache.Clear();
        }
        
        /// <summary>
        /// Arrête de cache
        /// </summary>
        public void Stop()
        {
            QueryCache.Stop();
        }

        /// <summary>
        /// Teste si un valeur existe
        /// </summary>
        /// <param name="value">Valeur a tester</param>
        /// <returns>bool</returns>
        public bool Exist(Tvalue value)
        {
            return QueryCache.Exist(value);
        }

        /// <summary>
        /// Obtiens des données depuis le cache
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public Tdata Get(Tvalue value)
        {
            return QueryCache.Get(value);
        }

        /// <summary>
        /// Durée de vie des données dans le cache
        /// </summary>
        public int LifeTime
        {
            get { return QueryCache.LifeTime;  }
            set { QueryCache.LifeTime = value; }
        }

        #endregion



        #region Event

        /// <summary>
        /// Fonction attaché a l'arret du cache
        /// </summary>
        private static void StopCache_StopTheCache(object sender, EventArgs e)
        {
            QueryCache.Clear();
        }

        #endregion
    }
}
